/**
 * @file listefichier.c
 * @brief Fichier source du module listefichier.
 *
 * @author Rachid Delory, Mamadou Keita, Florian Bernard
 */

/* *********************************************************************

   Librairies de listeFichier

   ********************************************************************* */

#include "listefichier.h"

/* *********************************************************************

   Fonctions

   ********************************************************************* */

int testExtension_Lfi(const gchar *name)
{
  GHashTable *table;
  int values = 0;
  char *extension;

  extension = strrchr(name, '.');
  if(extension == NULL)
    return AUCUN_LFI;
  
  table = g_hash_table_new(g_str_hash, g_int_equal);
  
  g_hash_table_insert(table, ".mp3", (gpointer)MUSIQUE_LFI);
  g_hash_table_insert(table, ".ogg", (gpointer)MUSIQUE_LFI);
  g_hash_table_insert(table, ".avi", (gpointer)FILM_LFI);
  g_hash_table_insert(table, ".mp4", (gpointer)FILM_LFI);
  g_hash_table_insert(table, ".jpeg", (gpointer)LIVRE_LFI);
  values = (int)g_hash_table_lookup(table, extension);
  g_hash_table_destroy(table);
  
  if(values == 0)
    return AUCUN_LFI;
  return values;
}

/* Returns the FIRST string of a text frame
 */
char *get_text_frame(struct id3_tag *tag, 
		     const char * id, 
		     int *ret_nstrings,
		     int idField)
{
  union id3_field const *field;
  unsigned int nstrings;
  struct id3_frame const *frame;
  id3_ucs4_t const *ucs4;
  id3_latin1_t *latin1;

  if(id ==NULL && id[0] != 'T')
    return NULL;

  frame = id3_tag_findframe(tag, id, idField);
  if(frame == 0)
    return 0;

  field = &frame->fields[1];
  nstrings = id3_field_getnstrings(field);
  if(nstrings == 0)
    return 0;
  if(ret_nstrings)
    *ret_nstrings = nstrings;

  ucs4 = id3_field_getstrings(field, idField);
  if(ucs4 == NULL)
    return NULL;
  
  if(strcmp(id, ID3_FRAME_GENRE) == 0)
    ucs4 = id3_genre_name(ucs4);

  latin1 = id3_ucs4_latin1duplicate(ucs4);

  return (char *)latin1;
}

char* id3_get_binary (struct id3_tag *tag, char *frame_name, id3_length_t *len, int index, const char *nomMusique)
{
  const id3_byte_t *binary = NULL;
  struct id3_frame *frame;
  union id3_field *field;
  char *fichier = NULL;
  g_return_val_if_fail (len, NULL);
  
  *len = 0;
  frame = id3_tag_findframe (tag, frame_name, index);
  
  if (!frame) return NULL;
  
  /* The last field contains the data */
  field = id3_frame_field (frame, frame->nfields-1);
  
  if (!field) return NULL;
  
  switch (field->type)
    {
    case ID3_FIELD_TYPE_BINARYDATA:
      binary = id3_field_getbinarydata(field, len);
      break;
    default:
      break;
    }
  
  {
    FILE *file;
    char *chemin = "data/illustration/";

    char num[5];
    int i = 0;
    num [0] = '\0';
    while(fichier == NULL)
      {
	char *tmp = NULL;
	sprintf(num, "%d", i);
	tmp = (char *) malloc ((strlen(num) + strlen(nomMusique) + 5) *sizeof(char));
	strcpy(tmp, nomMusique);
	strcat(tmp, num);
	strcat(tmp, ".jpg");
	fichier = g_build_filename(chemin, tmp, NULL);
	free(tmp);
	if(g_file_test(fichier, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) == TRUE)
	  {
	    free(fichier);
	    fichier = NULL;
	  }
	i++;
      }
    file = fopen (fichier, "w");
    if(file != NULL)
      {
	fwrite (binary, 1, *len, file);
	fclose (file);
      }
  }

  return fichier;
}

char *id3_apic_read (const gchar *filename, 
			       const char *nom)
{
  struct id3_file *id3file;
  struct id3_tag *id3tag;
  char *coverart = NULL;
  g_return_val_if_fail (filename, FALSE);

  if (!(id3file = id3_file_open (filename, ID3_FILE_MODE_READONLY)))
    {
      g_print("ERREUR lors de l'ouverture\n");
      return NULL;
    }

  if ((id3tag = id3_file_tag(id3file)))
    {
      id3_length_t len;
      int i;
      struct id3_frame *frame;

      /* Loop through APIC tags and set coverart.  The picture type should be
       * 3 -- Cover (front), but iTunes has been known to use 0 -- Other. */
      for (i = 0; (frame = id3_tag_findframe(id3tag, "APIC", i)) != NULL; i++)
	{
	  union id3_field *field = id3_frame_field (frame, 2);
	  int pictype = field->number.value;

          /* We'll prefer type 3 (cover) over type 0 (other) */
          if (pictype == 3)
	    {
	      coverart = id3_get_binary (id3tag, "APIC", &len, i, nom);
	      break;
	    }
	  if ((pictype == 0) && !coverart)
	    {
	      coverart = id3_get_binary (id3tag, "APIC", &len, i, nom);
	    }
	}
    }
  id3_file_close (id3file);
  return coverart;
}

Arbre * listeDossierArbre_Lfi(const char *dossier, int type)
{
  GDir *dir = g_dir_open(dossier, 0, NULL);
  Arbre *arbre = NULL;
  Regroupement *rgp = creer_Reg();
  gchar *basename = g_path_get_basename(dossier);
  setTitre_Reg(rgp, basename);
  arbre = creer_Arb(rgp);
  detruire_Reg(&rgp);    

  if(dir)
    {
      const gchar *filename = NULL;
      
      while((filename = g_dir_read_name(dir)) != NULL)
	{
	  char *absoluteFile = NULL;
		  
	  absoluteFile = g_build_filename(dossier, filename, NULL);
	  
	  if(g_file_test(absoluteFile, G_FILE_TEST_IS_REGULAR))
	    {
	      Oeuvre *oeuvre = NULL;
	      Livre *livre;
	      Musique *musique;
	      Film *film;
	      
	      oeuvre = creer_Oeu();
	      
	      setTitre_Oeu(oeuvre, filename);

	      /* En fonction de l'extension */

	      switch(testExtension_Lfi(filename))
		{
		case FILM_LFI :
		  if(type == FILM_LFI)
		    {
		      film = creer_Fil();
		      setType_Oeu(oeuvre, FILM_OEU);
		      setMedia_Oeu(oeuvre, film, copier_Fil);
		      detruire_Fil(&film);
		    }
		  else
		    detruire_Oeu(&oeuvre);
		  break;
		case MUSIQUE_LFI :
		  if(type == MUSIQUE_LFI)
		    {
		      musique = creer_Mus();
		      setType_Oeu(oeuvre, MUSIQUE_OEU);
		      setMedia_Oeu(oeuvre, musique, copier_Mus);
		      detruire_Mus(&musique);
		      {
			struct id3_file *file;
			struct id3_tag *tag;
	
			char *value = NULL;
			file = id3_file_open(absoluteFile,
					     ID3_FILE_MODE_READONLY);
			tag = id3_file_tag(file);
			value =  get_text_frame(tag, ID3_FRAME_TITLE, NULL, 0);
			if(value != NULL)
			  {
			    setTitre_Oeu(oeuvre, value);
			    free(value);
			  }
			value = get_text_frame(tag, ID3_FRAME_ALBUM, NULL, 0);
			if(value != NULL)
			  {
			    setTitre_Reg(getInformation(arbre), value);
			    free(value);
			  }
			value = get_text_frame(tag, ID3_FRAME_TRACK, NULL, 0);
			if(value != NULL)
			  {
			    char *value2;
			    value2 = strchr(value,'/');
			    if (value2)
			      {
				/*
				trackTotal = g_strdup_printf ("%.2d", atoi (value2+1));
				*/
				*value2 = '\0';

			      }
			    setPiste_Mus(getMedia_Oeu(oeuvre), atoi(value));
			    free(value);
			  }
			value = get_text_frame(tag, ID3_FRAME_YEAR, NULL, 0);
			if(value != NULL)
			  {
			    Date *date = creer_Dat();
			    
			    setAnnee_Dat(date, atoi(value));
			    setDateSortie_Oeu(oeuvre, date);
			    detruire_Dat(&date);
			    free(value);
			  }
			value = get_text_frame(tag, ID3_FRAME_COMMENT, NULL, 0);
			if(value != NULL)
			  {
			    setCommentaire_Oeu(oeuvre, value);
			    free(value);
			  }
			/** TODO Genre ID3_FRAME_GENRE */
			{
			  value = get_text_frame(tag, ID3_FRAME_GENRE, NULL, 0);
			  if(value != NULL)
			    {
			      printf("%s\n", value);
			      free(value);
			    }
			}
			{
			  char * fichier;
			  fichier = id3_apic_read(absoluteFile, getTitre_Oeu(oeuvre));
			  if(fichier)
			    {
			      setIllustration_Oeu(oeuvre, fichier);
			      free(fichier);
			    }
			}
			id3_tag_delete(tag);
			id3_file_close(file);
		      }
		    }
		  else
		    detruire_Oeu(&oeuvre);
		  break;
		case LIVRE_LFI :
		  if(type != LIVRE_LFI)
		    {
		      setIllustration_Reg(getInformation(arbre), absoluteFile);
		      detruire_Oeu(&oeuvre);
		    }
		  else
		    {
		      livre = creer_Liv();
		      setType_Oeu(oeuvre, LIVRE_OEU);
		      setMedia_Oeu(oeuvre, livre, copier_Liv);
		      detruire_Liv(&livre);
		    }
		  break;
		default:
		  detruire_Oeu(&oeuvre);
		  break;
		}

	      if(oeuvre != NULL)
		{
		  setLienMedia_Oeu(oeuvre, absoluteFile);
		  ajoutFeuille_Arb(arbre, oeuvre);
		  detruire_Oeu(&oeuvre);
		}
	      
	    }
	  else if(g_file_test(absoluteFile, G_FILE_TEST_IS_DIR))
	    {
	      ajoutNoeud_Arb(arbre, listeDossierArbre_Lfi(absoluteFile, type));
	    }

	  if(absoluteFile)
	    {
	      free(absoluteFile);
	    }
	}
      g_dir_close(dir);
    }
  if(basename)
    free(basename);

  return arbre;
}
